package com.lucy.flow.provider;

import com.lucy.common.constant.HttpStatus;
import com.lucy.common.exception.BusinessException;
import com.lucy.flow.constant.AssignTypeConst;
import com.lucy.flow.domain.entity.FlowNodeAssign;
import com.lucy.flow.loader.TaskUserLoader;
import com.lucy.rabc.entity.SysRole;
import com.lucy.rabc.entity.SysUser;
import com.lucy.rabc.service.SysDeptService;
import com.lucy.rabc.service.SysRoleService;
import com.lucy.rabc.service.SysUserService;
import io.netty.util.concurrent.CompleteFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author kindear
 * 任务审核人员获取方法提供
 * 如不存在 模块依赖关系，可以在 admin 模块中实现该方法
 */
@Slf4j
@Service
public class TaskUserProvider implements TaskUserLoader {
    @Autowired
    SysUserService userService;

    @Autowired
    SysDeptService deptService;

    @Autowired
    SysRoleService roleService;

    @Override
    public CompletableFuture<List<Long>> load(String assignType, String assignId) {
        if (AssignTypeConst.DEPT.equals(assignType)){
            return CompletableFuture.supplyAsync(() -> {
                    SysUser user = new SysUser();
                    user.setDeptId(Long.parseLong(assignId));
                    Example<SysUser> example = Example.of(user);
                    List<SysUser> users = userService.getExample(example);
                    return users.stream().map(SysUser::getId).collect(Collectors.toList());
            });
        }
        else if (AssignTypeConst.ROLE.equals(assignType)){
            return CompletableFuture.supplyAsync(() -> {
                // 如果是角色
                    Optional<SysRole> roleOp = roleService.getOne(Long.parseLong(assignId));
                    if (!roleOp.isPresent()) {
                        throw new BusinessException(HttpStatus.NOT_FOUND);
                    }
                    SysRole role = roleOp.get();
                    // 获取角色用户
                    Set<SysUser> users = role.getUsers();
                    // 获取用户ID列表
                    return users.stream().map(SysUser::getId).collect(Collectors.toList());
            });
        }else if (AssignTypeConst.USER.equals(assignType)){
            return CompletableFuture.supplyAsync(() -> {
                    List<Long> userIds = new ArrayList<>();
                    userIds.add(Long.parseLong(assignId));
                    return userIds;
            });

        }

        return null;
    }

    @Override
    public List<Long> load(List<FlowNodeAssign> assigns) {
        List<CompletableFuture<List<Long>>> taskList =
                assigns.stream().map(ele -> load(ele.getAssignType(),ele.getAssignId())).collect(Collectors.toList());
        CompletableFuture<Void> allFutures = CompletableFuture
                .allOf ((CompletableFuture<?>) taskList);
        // 下面的方法可以帮助我们获得所有子任务的处理结果
        Set<Long> idSet = new HashSet<>();
        for (CompletableFuture<List<Long>> future:taskList){
            idSet.addAll(future.join());
        }
        return new ArrayList<>(idSet);
    }
}
